package agent_service

import (
	"context"
	"log"

	_ "github.com/cloudwego/eino/components/model"

	"github.com/cloudwego/eino-ext/components/model/openai"
	"github.com/cloudwego/eino/components/prompt"
	"github.com/cloudwego/eino/schema"
)

// BaseAgent 是基于eino框架的基础智能体结构
// 提供了智能体的核心组件和通用功能，其他特定功能的智能体可以继承此结构
// 主要组成部分包括：模型、提示词、提示词模板、工具集、配置和上下文管理
// 可以通过继承并扩展此结构来实现特定业务场景的智能体

type BaseAgent struct {
	// Model 语言模型实例，用于生成回答和推理
	Model *openai.ChatModel

	// Prompt 基础提示词，定义智能体的角色和行为
	Prompt string

	// PromptTemplate 提示词模板，用于动态生成提示词
	PromptTemplate prompt.ChatTemplate

	// Tools 智能体可用的工具列表
	Tools []*schema.ToolInfo

	// Context 上下文管理器，用于存储和管理对话历史
	Context *AgentContext

	// Config 智能体配置，包括各种参数设置
	Config *AgentConfig

	BaseAgentInfo BaseAgentInfo
}

type AgentType string

const (
	BaseAgentType      AgentType = "base"
	ChatAgentType      AgentType = "chat"
	ReasoningAgentType AgentType = "reasoning"
	MultiAgentType     AgentType = "multi"
)

type BaseAgentInfo struct {
	// Name 智能体名称
	Name string

	// Description 智能体描述
	Description string

	// Version 智能体版本号
	Version string

	// Type 智能体类型，用于区分不同的智能体实现
	Type AgentType
}

// AgentContext 智能体上下文管理
// 负责存储和管理对话历史，维护对话状态

type AgentContext struct {
	// Messages 对话历史消息列表
	Messages []*schema.Message

	// MaxHistoryLength 最大历史记录长度，防止上下文过长
	MaxHistoryLength int
}

// AgentConfig 智能体配置结构
// 包含智能体运行时的各种配置参数

type AgentConfig struct {
	// Temperature 生成回答的随机度，0-1之间，值越大越随机
	Temperature float64

	// TopP 核采样参数，控制生成内容的多样性
	TopP float64

	// MaxTokens 最大生成的token数量
	MaxTokens int

	// EnableTools 是否启用工具调用
	EnableTools bool

	// EnableMemory 是否启用记忆功能
	EnableMemory bool
}

// NewBaseAgent 创建一个新的基础智能体实例
// 参数：
//   - model: 语言模型实例
//   - prompt: 基础提示词
//   - tools: 可用工具列表
// 返回值：
//   - *BaseAgent: 初始化后的基础智能体实例

func NewBaseAgent(model *openai.ChatModel, promptMessage string, tools []*schema.ToolInfo) *BaseAgent {
	// 创建默认配置
	config := &AgentConfig{
		Temperature:  0.7,
		TopP:         0.9,
		MaxTokens:    1024,
		EnableTools:  true,
		EnableMemory: true,
	}

	// 创建上下文管理器
	context := &AgentContext{
		Messages:         make([]*schema.Message, 0),
		MaxHistoryLength: 20, // 默认保留20条消息
	}

	// 初始化并返回智能体实例
	return &BaseAgent{
		Model:   model,
		Prompt:  promptMessage,
		Tools:   tools,
		Context: context,
		Config:  config,
	}
}

// AddMessage 添加消息到对话历史
// 参数：
//   - msg: 要添加的消息
// 功能：将消息添加到上下文中，并确保历史记录不超过最大长度

func (a *BaseAgent) AddMessage(msg *schema.Message) {
	if a.Context == nil {
		log.Println("警告: Agent上下文未初始化")
		return
	}

	// 添加消息到对话历史
	a.Context.Messages = append(a.Context.Messages, msg)

	// 限制历史记录长度
	if len(a.Context.Messages) > a.Context.MaxHistoryLength {
		// 移除最旧的消息，保留系统消息（如果有）
		newHistory := make([]*schema.Message, 0)
		for i := len(a.Context.Messages) - a.Context.MaxHistoryLength; i < len(a.Context.Messages); i++ {
			newHistory = append(newHistory, a.Context.Messages[i])
		}
		a.Context.Messages = newHistory
		log.Printf("对话历史过长，已裁剪至%d条消息", a.Context.MaxHistoryLength)
	}
}

// ClearHistory 清空对话历史
// 功能：重置上下文中的对话历史消息列表

func (a *BaseAgent) ClearHistory() {
	if a.Context != nil {
		a.Context.Messages = make([]*schema.Message, 0)
		log.Println("对话历史已清空")
	}
}

// GenerateResponse 生成智能体响应
// 参数：
//   - ctx: 上下文
//   - userInput: 用户输入内容
// 返回值：
//   - *schema.Message: 生成的响应消息
//   - error: 错误信息
// 功能：处理用户输入，生成智能体响应，并维护对话历史

func (a *BaseAgent) GenerateResponse(ctx context.Context, userInput string) (*schema.Message, error) {
	if a.Model == nil {
		return nil, ErrModelNotInitialized
	}

	// 创建用户消息
	userMsg := &schema.Message{
		Role:    schema.User,
		Content: userInput,
	}

	// 添加用户消息到历史记录
	a.AddMessage(userMsg)

	// 构建完整的提示词
	finalPrompt := a.Prompt + "\n" + userInput

	// 创建系统消息（如果还没有）
	hasSystemMessage := false
	for _, msg := range a.Context.Messages {
		if msg.Role == schema.System {
			hasSystemMessage = true
			msg.Content = finalPrompt // 更新系统消息内容
			break
		}
	}

	// 如果没有系统消息，则添加一个
	if !hasSystemMessage {
		systemMsg := &schema.Message{
			Role:    schema.System,
			Content: finalPrompt,
		}
		// 插入到消息列表的开头
		newMessages := append([]*schema.Message{systemMsg}, a.Context.Messages...)
		a.Context.Messages = newMessages
	}

	// 生成响应
	resp, err := a.Model.Generate(ctx, a.Context.Messages)
	if err != nil {
		log.Printf("生成响应失败: %v", err)
		return nil, err
	}

	// 添加响应到历史记录
	a.AddMessage(resp)

	return resp, nil
}

// RegisterTool 注册工具到智能体
// 参数：
//   - tool: 要注册的工具信息
// 功能：将工具添加到智能体的工具列表中

func (a *BaseAgent) RegisterTool(tool *schema.ToolInfo) {
	if a.Tools == nil {
		a.Tools = make([]*schema.ToolInfo, 0)
	}
	a.Tools = append(a.Tools, tool)
	log.Printf("工具已注册: %s", tool.Name)
}

// UpdateConfig 更新智能体配置
// 参数：
//   - config: 新的配置
// 功能：更新智能体的运行时配置

func (a *BaseAgent) UpdateConfig(config *AgentConfig) {
	a.Config = config
	log.Println("智能体配置已更新")
}

// 错误定义
var (
	ErrModelNotInitialized   = &AgentError{"模型未初始化"}
	ErrPromptEmpty           = &AgentError{"提示词为空"}
	ErrContextNotInitialized = &AgentError{"上下文未初始化"}
)

// AgentError 智能体错误类型
type AgentError struct {
	Message string
}

// Error 返回错误信息
func (e *AgentError) Error() string {
	return e.Message
}

// BaseAgentFunction 基础智能体函数接口
// 定义了智能体可以执行的函数的基本行为
type BaseAgentFunction interface {
	//执行函数
	Execute(ctx context.Context, args []string) (string, error)
}
